#include <UnitTest++.h>
#include "formule.hpp"
#include "parser.hpp"
#include "dimacs.hpp"
#include <iostream>
#include <sstream>
#include <fstream>

// Un test simple qui réussit
TEST(test1)
{
  CHECK(2 == 1+1);
}

// Un test simple qui échoue
/*
TEST(test2)
{
  CHECK(2 == 1+2);
}*/

 /* ------------ Exercices sur les clauses -------------------- */
TEST(clauses2)
{
    cls_t cl1;
    cls_t cl2; // clause de notre choix pour le test
    //Écrire un TEST qui crée une clause cl1 contenant les littéraux 1, 4, 7 et 6
// et une autre clause cl2 de votre choix puis les affiche.

    cl1={1,4,7,6};//on crée cl1 et cl2 à la main
    cl2={3,5,8,9};

    //les test (Écrire un TEST avec les vérifications suivantes) :
    CHECK(cl1 != cl2);
    CHECK(cl2 != cl1);
    CHECK(cl1 == cl1);
    CHECK(cl2 == cl2);
    cout<< "TEST(clauses2) réussis "<<endl;
        cout<<endl;
}

             /* --------Exercices sur CNF------- */

// Ajouter un TEST pour l'affichage d'une CNF c contenant les clauses cl1 et cl2.
TEST(cnf1)
{
    cls_t cl1={7,6,1,4,1};
    cls_t cl2={5,4,3,2,1};

    cnf_t cnf1={cl1,cl2};
    cout << cnf1 << endl;

}

TEST(cnf1bis) // pour l'affichage d'une cnf
{
    cls_t cl1 = {6,9,7,6};
        cls_t cl2 = {52,3};

        cnf_t c = {cl1,cl2};
        c.insert(c.end(),{{15,69},{71,74,75}}); //on ajoute a la cnf des clauses

        c.insert(c.end(),{{11,7,8,3},{3,9,4}});

        cout<< "TEST(cnf1) affichage cnf :  "<<endl;
        cout<<endl;
        operator<<(cout,c);

	cout<< "TEST(cnf1) réussis  "<<endl;

}

//Écrire un TEST pour vérifier notamment que est_dans(cl1, c) et que est_dans(cl2, c).
TEST(EstDans) // pour est_dans
{
  cls_t clause1={7,6,1,4,1}; // clause 1 équivalent a cl1 dans l'énnoncé
  cls_t clause2={5,4,3,2,1}; // clause 2 équivalent a cl2 dans l'énnoncé

  cnf_t tableau_litteraux={clause1,clause2,{1,2,3}}; // CNF

  CHECK(est_dans(clause1, tableau_litteraux) && est_dans(clause2,tableau_litteraux));

      cout<<endl;
    cout << "TEST(EstDans) sucess "<<endl;
    cout << "la clause 1 EST DANS la cnf "<<endl;
    cout <<" ET la clause 2 EST DANS la cnf"<<endl;
cout<<endl;
  /*
  else
  {
    cout << "la clause 1 et la clause 2 ne sont pas dans la cnf" << endl;
  }*/

}

/* ---------------Exercices sur les littéraux------------------ */


// Exemple de test des fonctions de lecture et d'écriture au format dimacs
TEST(lit_ecrit_dimacs) {
    cnf_t cnf;
    cnf.push_back({1,3,4,7});
    cnf.push_back({2,3});
    ostringstream out;
    for(auto it = cnf.cbegin(); it != cnf.cend(); ++it) {
        ecrit_clause_dimacs(out,*it);
    }
    istringstream in(out.str());
    dimacs d;
    lit_dimacs(in,d);
    auto it1 = cnf.cbegin();
    auto it2 = d.cnf.cbegin();
    while (it1 != cnf.cend() && it2 != d.cnf.cend()) {
        CHECK(*it1 == *it2);
        ++it1;
        ++it2;
    }
    CHECK(d.nbVars == 4);
cout<< "TEST(lit_ecrit_dimacs) réussis  "<<endl;
}

TEST(lit_probleme1)
{
  ifstream input("test-data/pb-simple1.txt");
  probleme pb = lit_probleme(input);
  CHECK(pb.nb_enseignants == 1);
  CHECK(pb.nb_salles == 1);
  CHECK(pb.nb_creneaux == 2);
  CHECK(pb.nb_cours == 2);
  CHECK(pb.enseigne[0] == set<int>({1,0}));
  CHECK(pb.salles[0] == set<int>({0}));
  CHECK(pb.salles[1] == set<int>({0}));
  CHECK(pb.indisponibilites[0] == set<int>({0}));

	cout<< "TEST(lit_probleme1) réussis  "<<endl;
}

TEST(lit_probleme2)
{
  ifstream input("test-data/pb-simple2.txt");
  probleme pb = lit_probleme(input);
  CHECK(pb.nb_enseignants == 2);
  CHECK(pb.nb_salles == 1);
  CHECK(pb.nb_creneaux == 2);
  CHECK(pb.nb_cours == 2);
  CHECK(pb.enseigne[0] == set<int>({1,0}));
  CHECK(pb.salles[0] == set<int>({0}));
  CHECK(pb.salles[1] == set<int>({0}));
  CHECK(pb.indisponibilites[0] == set<int>({0,1}));
  cout<< "TEST(lit_probleme2) réussis  "<<endl;
}

TEST(lit_probleme4)
 {
  ifstream input("test-data/pb-simple4.txt");
  probleme pb = lit_probleme(input);
  CHECK(pb.nb_enseignants == 2);
  CHECK(pb.nb_salles == 2);
  CHECK(pb.nb_creneaux == 2);
  CHECK(pb.nb_cours == 3);
  CHECK(pb.enseigne[0] == set<int>({1,0,2}));
  CHECK(pb.enseigne[1] == set<int>({1,0}));
  CHECK(pb.salles[0] == set<int>({0}));
  CHECK(pb.salles[1] == set<int>({0}));
  CHECK(pb.salles[2] == set<int>({0,1}));
  CHECK(pb.indisponibilites[0] == set<int>({0,1}));
  cout<< "TEST(lit_probleme4) réussis  "<<endl;
}

int main()
{
	cout<<"hello  BAH THIERNO Souleymane & Alexandre PORTE. VOS TESTS: "<<endl;
  return UnitTest::RunAllTests(); // un peu magique: lance tous les tests
}
